package com.cyys.common.thirdInterface.aliyun;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSSClient;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.vod.model.v20170321.*;
import com.cyys.common.thirdInterface.ThirdConfig;
import com.cyys.common.utils.Encodes;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 阿里云视频点播 工具类
 */
public class VodUtil {

    public static DefaultAcsClient initVodClient() throws ClientException {
        String regionId = "cn-shanghai";  // 点播服务接入区域
        DefaultProfile profile = DefaultProfile.getProfile(regionId, ThirdConfig.ALY_VOD_ACCESS_KEYID, ThirdConfig.ALY_VOD_ACCESS_KEYSECRET);
        DefaultAcsClient client = new DefaultAcsClient(profile);
        return client;
    }

    /**
     * 获取视频上传地址和凭证
     * @param title 上传之后文件名称
     * @param fileName 本地文件路径和名称
     */
    public static CreateUploadVideoResponse createUploadVideo(DefaultAcsClient client, String title, String fileName) throws Exception {
        CreateUploadVideoRequest request = new CreateUploadVideoRequest();
        request.setTitle(title);
        request.setFileName(fileName);
        //设置请求超时时间
//        request.setSysReadTimeout(1000);
//        request.setSysConnectTimeout(1000);
        return client.getAcsResponse(request);
    }

    /**
     * 刷新视频上传凭证
     * @return RefreshUploadVideoResponse 刷新视频上传凭证响应数据
     * @throws Exception
     */
    public static RefreshUploadVideoResponse refreshUploadVideo(DefaultAcsClient client, String videoId) throws Exception {
        RefreshUploadVideoRequest request = new RefreshUploadVideoRequest();
        request.setAcceptFormat(FormatType.JSON);
        request.setVideoId(videoId);
        return client.getAcsResponse(request);
    }

    public static OSSClient initOssClient(JSONObject uploadAuth, JSONObject uploadAddress) {
        String endpoint = uploadAddress.getString("Endpoint");
        String accessKeyId = uploadAuth.getString("AccessKeyId");
        String accessKeySecret = uploadAuth.getString("AccessKeySecret");
        String securityToken = uploadAuth.getString("SecurityToken");
        return new OSSClient(endpoint, accessKeyId, accessKeySecret, securityToken);
    }

    public static void uploadLocalFile(OSSClient ossClient, JSONObject uploadAddress, String localFile){
        String bucketName = uploadAddress.getString("Bucket");
        String objectName = uploadAddress.getString("FileName");
        File file = new File(localFile);
        ossClient.putObject(bucketName, objectName, file);
    }

    public static void uploadLocalFile(OSSClient ossClient, JSONObject uploadAddress, InputStream input){
        String bucketName = uploadAddress.getString("Bucket");
        String objectName = uploadAddress.getString("FileName");
        ossClient.putObject(bucketName, objectName, input);
    }

    /**
     * URL批量拉取上传
     * @param  uploadMetadataList
     * @return UploadMediaByURLResponse URL批量拉取上传响应数据
     * @throws Exception
     */
    public static UploadMediaByURLResponse uploadMediaByURL(DefaultAcsClient client, JSONArray uploadMetadataList) throws Exception {
        UploadMediaByURLRequest request = new UploadMediaByURLRequest();
//        String url = "http://xxxx.mp4";
//        String encodeUrl = URLEncoder.encode(url, "UTF-8");
//        request.setUploadURLs(encodeUrl);
//
//        JSONObject uploadMetadata = new JSONObject();
//        uploadMetadata.put("SourceUrl", encodeUrl);
//        uploadMetadata.put("Title", "upload by url sample");
//
//        JSONArray uploadMetadataList = new JSONArray();
//        uploadMetadataList.add(uploadMetadata);
        request.setUploadMetadatas(uploadMetadataList.toJSONString());

        JSONObject userData = new JSONObject();

        JSONObject messageCallback = new JSONObject();
        messageCallback.put("CallbackURL", "http://192.168.0.0/16");
        messageCallback.put("CallbackType", "http");
        userData.put("MessageCallback", messageCallback.toJSONString());

        JSONObject extend = new JSONObject();
        extend.put("MyId", "user-defined-id");
        userData.put("Extend", extend.toJSONString());

        request.setUserData(userData.toJSONString());

        return client.getAcsResponse(request);
    }


    /**
     * 获取URL上传信息
     * @return GetURLUploadInfosResponse 获取URL上传信息响应数据
     * @throws Exception
     */
    public static GetURLUploadInfosResponse getURLUploadInfos(DefaultAcsClient client, String[] urls) throws Exception {
        GetURLUploadInfosRequest request = new GetURLUploadInfosRequest();
        List<String> encodeUrlList = new ArrayList<String>();
        for(String url : urls){
            encodeUrlList.add(URLEncoder.encode(url, "UTF-8"));
        }
        request.setUploadURLs(StringUtils.join(encodeUrlList, ','));
        return client.getAcsResponse(request);
    }

    /*获取播放地址函数*/
    public static GetPlayInfoResponse getPlayInfo(DefaultAcsClient client, String videoId) throws Exception {
        GetPlayInfoRequest request = new GetPlayInfoRequest();
        request.setVideoId(videoId);
        return client.getAcsResponse(request);
    }

    /*获取播放地址函数*/
    public static Map<String,String> getPlayInfo(String videoId) throws Exception {
        DefaultAcsClient client = initVodClient();
        GetPlayInfoRequest request = new GetPlayInfoRequest();
        request.setVideoId(videoId);
        GetPlayInfoResponse response= client.getAcsResponse(request);
        Map<String,String> retMap= new HashMap<String,String>(){{
            put("playUrl", response.getPlayInfoList().get(0).getPlayURL());
        }};
        return retMap;
    }

    /*获取播放凭证函数(用于前端播放)*/
    public static GetVideoPlayAuthResponse getVideoPlayAuth(DefaultAcsClient client, String videoId) throws Exception {
        GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest();
        request.setVideoId(videoId);
        return client.getAcsResponse(request);
    }

    /*修改视频信息*/
    public static UpdateVideoInfoResponse updateVideoInfo(DefaultAcsClient client, UpdateVideoInfoRequest request) throws Exception {
        return client.getAcsResponse(request);
    }

    /*删除视频信息*/
    public static DeleteVideoResponse updateVideoInfo(DefaultAcsClient client, String videoIds) throws Exception {
        DeleteVideoRequest request= new DeleteVideoRequest();
        request.setVideoIds(videoIds);
        return client.getAcsResponse(request);
    }


    /**
     * 视频上传
     * @param title 上传之后文件名称
     * @param fileName 本地文件路径和名称
     */
    public static String uploadVideo(String title, String fileName)throws Exception{
//        AjaxJson ajx= new AjaxJson();
        // 初始化VOD客户端并获取上传地址和凭证
        DefaultAcsClient vodClient = initVodClient();
        CreateUploadVideoResponse createUploadVideoResponse = createUploadVideo(vodClient,title, fileName);
        // 执行成功会返回VideoId、UploadAddress和UploadAuth
        String videoId = createUploadVideoResponse.getVideoId();
        JSONObject uploadAuth = JSONObject.parseObject(Encodes.decodeBase64String(createUploadVideoResponse.getUploadAuth()));
        JSONObject uploadAddress = JSONObject.parseObject(Encodes.decodeBase64String(createUploadVideoResponse.getUploadAddress()));
        // 使用UploadAuth和UploadAddress初始化OSS客户端
        OSSClient ossClient = initOssClient(uploadAuth, uploadAddress);
        // 上传文件，注意是同步上传会阻塞等待，耗时与文件大小和网络上行带宽有关
        uploadLocalFile(ossClient, uploadAddress, fileName);
//        ajx.setSuccess(true);
//        ajx.put("videoId", videoId);
//        return ajx;
        GetPlayInfoResponse response= getPlayInfo(initVodClient(),videoId);
        GetPlayInfoResponse.VideoBase base= response.getVideoBase();
        return videoId;
    }

    /**
     * 视频上传
     * @param title 上传之后文件名称
     * @param fileName 本地文件路径和名称
     * @param input 文件輸入流
     * @return
     * @throws Exception
     */
    public static String uploadVideo(String title, String fileName, InputStream input)throws Exception{
        // 初始化VOD客户端并获取上传地址和凭证
        DefaultAcsClient vodClient = initVodClient();
        CreateUploadVideoResponse createUploadVideoResponse = createUploadVideo(vodClient,title, fileName);
        // 执行成功会返回VideoId、UploadAddress和UploadAuth
        String videoId = createUploadVideoResponse.getVideoId();
        JSONObject uploadAuth = JSONObject.parseObject(Encodes.decodeBase64String(createUploadVideoResponse.getUploadAuth()));
        JSONObject uploadAddress = JSONObject.parseObject(Encodes.decodeBase64String(createUploadVideoResponse.getUploadAddress()));
        // 使用UploadAuth和UploadAddress初始化OSS客户端
        OSSClient ossClient = initOssClient(uploadAuth, uploadAddress);
        // 上传文件，注意是同步上传会阻塞等待，耗时与文件大小和网络上行带宽有关
        uploadLocalFile(ossClient, uploadAddress, input);
        GetPlayInfoResponse response= getPlayInfo(initVodClient(),videoId);
        GetPlayInfoResponse.VideoBase base= response.getVideoBase();
        return videoId;
    }

    public static void main(String[] argv) {
        try {
            // 视频上传
//            String localFile = "D:/vod测试.mp4";
//            String localFile = "D:/life/MP3/张磊-寻.mp3";
//            AjaxJson ajx= uploadVideo("测试_vod", localFile);
//            System.out.println("上传成功，videoId" + ajx.getData().get("videoId"));
            GetPlayInfoResponse response= getPlayInfo(initVodClient(),"fd6fafc0add74646a70aa4906e532c54");
            GetPlayInfoResponse.VideoBase base= response.getVideoBase();
            System.out.println("上传失败: ");
            //c055596dc85e4c7890b1e05b9c281214
            //54b344db3d41441695cb728213fcc413
        } catch (Exception e) {
            System.out.println("上传失败: " + e.getLocalizedMessage());
        }
    }
}
